<template>
  <Modal v-model="isOpen" :closeOnMask="closeOnMask">
    <template v-if="hasHeaderSlot" #header>
      <slot name="header" :loading="loading" :cancel="cancel" :submit="submit"></slot>
    </template>
    <component :is="ContentComponent" :params="params" :dialog="dialog" @load="onLoad" @success="onSuccess" ref="content"></component>
    <template v-if="hasFooterSlot" #footer>
      <slot name="footer" :loading="loading" :cancel="cancel" :submit="submit"></slot>
    </template>
  </Modal>
</template>
<script>
  import {loadComponent,useEscapeStack} from 'framework'
  import {ref, defineAsyncComponent, useSlots} from 'vue'
  const escapeStack=[]
  const escapeListeners=(e)=>{
    if(e.key === "Escape"){
      if(escapeStack.length>=0){
        escapeStack[escapeStack.length-1](e)
      }
    }
  };
  export default {
    name: 'Dialog',
    props:{
      href: String,
      closeOnMask: {
        default: false,
        type: Boolean
      },
      closeOnPressEscape:{
        default:true,
        type:Boolean
      }
    },setup(props,{emit,expose}){
      const {href, closeOnMask,closeOnPressEscape}=props
      const hasHeaderSlot = !!useSlots().header
      const hasFooterSlot = !!useSlots().footer
      const params = ref(null)
      const ContentComponent = defineAsyncComponent(() => loadComponent(href))
      const content = ref(null)
      const isOpen = ref(false)
      const loading = ref(false)
      let submitListener=()=>{}

      const cancel=()=>{
        isOpen.value = false
        let idx=escapeStack.indexOf(cancel)
        if (idx>-1){
          escapeStack.splice(idx,1)
        }
        if(escapeStack.length==0){
          document.removeEventListener('keydown',escapeListeners)
        }
      }
      const dialog={
        loading(v){
          loading.value=v
        },
        onSubmit(cb){
          submitListener=cb
        },
        success(data){
          cancel()
          _resolve(data)
        },
        emit(e,data){
          emit(e,data)
        },
        cancel(){
          cancel()
        },
        submit(){
          return submit()
        }
      }
      //let _resolve;
      let _resolves=[]
      function _resolve(data){
        let rses=_resolves;
        _resolves=[];
        for(let rs of rses){
          rs(data)
        }

      }
      function open(_params) {
        isOpen.value = true
        if (closeOnPressEscape){
          escapeStack.push(cancel)
          if(escapeStack.length==1){
            document.addEventListener('keydown',escapeListeners)
          }
        }

        params.value = _params
        //console.log(content.value)
        return new Promise((resolve) => {
          //_resolve=resolve
          _resolves.push(resolve)
        })
      }

      // if(closeOnPressEscape){
      //   useEscapeStack(cancel)
      // }

      function onSuccess(data){
        cancel()
        _resolve(data)
      }
      function submit() {
        return new Promise(resolve=>{
          _resolves.push(resolve)
          submitListener()
          if(content.value.submit){
            content.value.submit(loading,onSuccess)
          }
        })
      }

      function onLoad(v){
        loading.value=v
      }
      expose({open, cancel, loading, submit,ref:content})
      return {
        isOpen,
        hasHeaderSlot,
        hasFooterSlot,
        ContentComponent,
        params,
        dialog,
        loading,
        cancel,
        submit,
        onLoad,
        onSuccess,
        content
      }
    }
  }
</script>
<!--<script setup>-->
<!--  import {loadComponent,useEscapeStack} from 'framework'-->
<!--  import {ref, defineAsyncComponent, useSlots} from 'vue'-->

<!--  const hasHeaderSlot = !!useSlots().header-->
<!--  const hasFooterSlot = !!useSlots().footer-->
<!--  const params = ref(null)-->
<!--  const {href, closeOnMask,closeOnPressEscape} = defineProps({-->
<!--    href: String,-->
<!--    closeOnMask: {-->
<!--      default: false,-->
<!--      type: Boolean-->
<!--    },-->
<!--    closeOnPressEscape:{-->
<!--      default:true,-->
<!--      type:Boolean-->
<!--    }-->
<!--  })-->

<!--  const ContentComponent = defineAsyncComponent(() => loadComponent(href))-->
<!--  const content = ref(null)-->
<!--  const isOpen = ref(false)-->
<!--  const loading = ref(false)-->
<!--  let submitListener=()=>{}-->
<!--  const emit=defineEmits()-->
<!--  const cancel=()=>{-->
<!--    isOpen.value = false-->
<!--  }-->
<!--  const dialog={-->
<!--    loading(v){-->
<!--      loading.value=v-->
<!--    },-->
<!--    onSubmit(cb){-->
<!--      submitListener=cb-->
<!--    },-->
<!--    success(data){-->
<!--      cancel()-->
<!--      _resolve(data)-->
<!--    },-->
<!--    emit(e,data){-->
<!--      emit(e,data)-->
<!--    },-->
<!--    cancel(){-->
<!--      cancel()-->
<!--    },-->
<!--    submit(){-->
<!--      return submit()-->
<!--    }-->
<!--  }-->
<!--  //let _resolve;-->
<!--  let _resolves=[]-->
<!--  function _resolve(data){-->
<!--    let rses=_resolves;-->
<!--    _resolves=[];-->
<!--    for(let rs of rses){-->
<!--      rs(data)-->
<!--    }-->

<!--  }-->
<!--  function open(_params) {-->
<!--    isOpen.value = true-->

<!--    params.value = _params-->
<!--    //console.log(content.value)-->
<!--    return new Promise((resolve) => {-->
<!--      //_resolve=resolve-->
<!--      _resolves.push(resolve)-->
<!--    })-->
<!--  }-->



<!--  if(closeOnPressEscape){-->
<!--    useEscapeStack(cancel)-->
<!--  }-->

<!--  function onSuccess(data){-->
<!--    cancel()-->
<!--    _resolve(data)-->
<!--  }-->
<!--  function submit() {-->
<!--    return new Promise(resolve=>{-->
<!--      _resolves.push(resolve)-->
<!--      submitListener()-->
<!--      if(content.value.submit){-->
<!--        content.value.submit(loading,onSuccess)-->
<!--      }-->
<!--    })-->
<!--  }-->

<!--  function onLoad(v){-->
<!--    loading.value=v-->
<!--  }-->
<!--  defineExpose({open, cancel, loading, submit,ref:content})-->
<!--</script>-->
